<?php

namespace App\Controller\Api;

use App\Base\BaseController4Restful;
use App\Entity\Comment;
use App\Entity\Task;
use App\Repository\TaskRepository;
use App\Service\AnnounceService;
use App\Service\TaskService;
use MongoDB\Driver\Exception\Exception;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use function Doctrine\ORM\QueryBuilder;

class ApiTaskController extends BaseController4Restful
{
    /**
     * @Route("/api/Tasks", name="apiGetTasks",methods={"GET","POST"})
     */
    public function apiGetTasks(TaskRepository $repository, Request $request,AnnounceService $announceService)
    {
        switch ($request->getMethod()) {
            case "POST":
                $user = $this->needToBeUser();
                $data = $this->getRequestData();
                $this->is->isCategory($data["cat1"]);
                $this->is->isCategory($data["cat2"]);
                $this->is->isString($data["callBefore"]);
                $this->is->isUserAddress($data["address"]);
                $this->is->isUserContact($data["contact"]);
                $this->is->isArray($data["pics"]);

                //计算值
                $data["createAt"] = new \datetime();
                $data["createAt"] = $data["createAt"]->format('c');
                $data["expireAt"] = new \datetime("+" . $data["expireAt"] . " days");
                $data["expireAt"] = $data["expireAt"]->format('c');

                /**@var $Task Task */
                $Task = $this->createEntity($data, Task::class);
                $Task->setSn($this->createOrderSn())
                    ->setStatus(0)
                    ->setType(1)
                    ->setUser($user);
                $this->myEm()->persist($Task);
                $this->myEm()->flush();

                //发布通知
                $announceService->dealWithTaskCreate($Task);

                return $this->json_out(200, "创建成功", $Task);
            default:
                if (!$page = $this->getParamRequired("page")) {
                    $page = 1;
                }
                $limit = 10;
                $offset = (int)abs($limit * ($page - 1));
                $total = $repository->count([]);
                $this->setMeta($page, $total, $limit);
                $list = $repository->findBy(array(), array(), $limit, $offset);
                return $this->json_out(200, "获取成功", $list);
        }
    }

    /**
     * @Route("/api/tasks/{id}", name="apiAddTasks",methods={"GET","PUT","PATCH","DELETE"})
     */
    public function apiUpdateTasks(Task $Task, Request $request)
    {
        $data = $this->getRequestData();
        switch ($request->getMethod()) {
            case "DELETE":
                $this->myEm()->remove($Task);
                $this->myEm()->flush();
                return $this->json_out(200, "已移除");
            case "PATCH":
            case "PUT":
                /**@var $Task Task */
                $Task = $this->updateEntity($data, Task::class, $Task);
                break;
            case "Get":
            default:
        }
        $this->myEm()->persist($Task);
        $this->myEm()->flush();
        return $this->json_out(200, "获取成功", $Task);
    }


    /**
     * @Route("/api/task/{id}/cancel", name="apiTaskCancel",methods={"GET","PUT","PATCH","DELETE"})
     */
    public function apiTaskCancel(Task $task)
    {
        $data = $this->getRequestData();
        $user = $this->needToBeUser();
        if ($task->getUser() != $user) {
            return $this->json_out(400,"权限不足");
        }
        if ($task->getStatus() > 0) {
            return $this->json_out(400,"任务已超过取消期限");
        }
        $this->myEm()->remove($task);
        $this->myEm()->flush();
        return $this->json_out(200,"删除成功",$data);
    }


    /**
     * @Route("/api/task/{id}/confirm", name="apiTaskConfirm",methods={"GET","PUT","PATCH","DELETE"})
     */
    public function apiTaskConfirm(Task $task,TaskService $service)
    {
        if (!$content = $this->getParamRequired("content")) {
            $content = "用户没有做出评价";
//            return $this->json_out(400,"请输入评价内容");
        }
        if (!$score = $this->getParamRequired("score")) {
            $score = 5;
//            return $this->json_out(400,"请输入评价内容");
        }
        $data = $this->getRequestData();
        $user = $this->needToBeUser();
        if ($task->getUser() != $user) {
            return $this->json_out(400,"权限不足");
        }
        if ($task->getStatus() >= 900) {
            return $this->json_out(400,"任务已确认");
        }
        //处理任务订单数据，及相关资金分配
        try {
            $service->dealWithTaskConfirm($task,$content,$score,1);
        } catch (Exception $exception) {
            return $this->json_out(500,"ERROR",$exception);
        }
        return $this->json_out(200,"确认成功",$data);
    }



    /**
     * 获取任务大厅的列表
     * 必须参数：lat,lon地理位置信息
     * 其他参数：
     *      page:页码
     *      distance：筛选范围，公里为单位
     *      expire：过期时间，天为单位
     *      keywords：文字搜索
     *      orderby:排序规则，1.默认不传参数orderby=""，即最新发布;2.距离最近，orderby=near;3....
     * @Route("/api/task/get/all", name="apiTaskGetAll",methods={"GET","PUT","PATCH","DELETE"})
     */
    public function apiTaskGetAll(TaskRepository $repository)
    {

        if (!$page = $this->getParamRequired("page")) {$page = 1;}
        if (!$orderby = $this->getParamRequired("orderby")) {$orderby = 0;}
        $qb = $repository->createQueryBuilder("A");
        $qb->select("A as task");
//            ->join("App:UserAddress","B","with","A.address = B");
        $qb->innerJoin("A.address","B");
        $qb->where("A.type = 1");//手动创建的任务
        $qb->andWhere("A.status < 199");//还能参与的状态
        $dateTime = date($this->YYMMDDHHIISS);
        $qb->andWhere("A.expireAt > '{$dateTime}'");//未过期的

        //地理位置
        if (!$lat = $this->getParamRequired("lat")) {$lat = 0;}
        if (!$lon = $this->getParamRequired("lon")) {$lon = 0;}
        if ($lat*$lon) {
            //地理位置排序
            $qb->addSelect("SQRT(($lat - B.lat)*($lat - B.lat) + ($lon  - B.lon)*($lon  - B.lon)) AS distance");
            if ($distance = $this->getParamRequired("distance")){
                //计算距离
                $latlon = calcLatLonFromDistance($distance*1000);
                $qb->andWhere("B.lat > ".($lat - $latlon) )
                    ->andWhere("B.lat < ".($lat + $latlon) )
                    ->andWhere("B.lon >= ".($lon - $latlon) )
                    ->andWhere("B.lon >= ".($lon - $latlon) );
            }
            //距离排序
            if ($orderby == "near") {$qb->orderBy("distance","ASC");}
        }

        //有效时间筛选
        if($expire = $this->getParamRequired("expire")){
            $dateTime = new \DateTime();
            $dateTime->setTimestamp(time() + $expire*24*3600);
            $targeDate = $dateTime;
            $qb->andWhere(
                $qb->expr()->lte("A.expireAt","'{$targeDate->format($this->YYMMDDHHIISS)}'")
            );
        }

        //文字搜索
        if($keywords = $this->getParamRequired("keywords")){
            $qb->andWhere(
                $qb->expr()->like("A.title","'%{$keywords}%'")
            );
        }


        if (!$orderby) {$qb->orderBy("A.createAt","DESC");}
        $qb->setMaxResults(10);
        $qb->setFirstResult($page * 10 - 10);
        $data = $qb->getQuery()->execute();

        foreach ($data as &$one) {
            $one["distance"] = isset($one["distance"])? round(calcDistanceFromLatLon($one["distance"]) / 1000,2):"";
        }


        $this->setGroups("task");
        return $this->json_out(200,"ok",$data);
    }
}
